package com.kantboot.functional.third.party.google.util.web.login;

import com.alibaba.fastjson2.annotation.JSONField;
import com.google.api.client.googleapis.auth.oauth2.GoogleIdToken;
import com.google.api.client.googleapis.auth.oauth2.GoogleIdTokenVerifier;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.http.javanet.NetHttpTransport;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.gson.GsonFactory;
import com.kantboot.functional.third.party.google.exception.ThirdPartyGoogleException;
import lombok.Data;
import lombok.SneakyThrows;
import lombok.experimental.Accessors;

import java.io.Serializable;
import java.util.Collections;

/**
 * 谷歌凭证信息
 * <a href="https://developers.google.com/identity/gsi/web/guides/verify-google-id-token?hl=zh-cn">
 * https://developers.google.com/identity/gsi/web/guides/verify-google-id-token?hl=zh-cn
 * </a>
 */
public class Credential2Info {

    @Data
    @Accessors(chain = true)
    public static class Param implements Serializable {
        /**
         * 谷歌凭证
         */
        private String credential;
    }

    @Data
    @Accessors(chain = true)
    public static class Result implements Serializable {
        /**
         * iss 该JWT的签发者
         */
        @JSONField(name = "iss")
        private String iss;

        /**
         * azp 该客户端的客户端ID
         */
        @JSONField(name = "azp")
        private String azp;

        /**
         * aud 接收该JWT的一方
         */
        @JSONField(name = "aud")
        private String aud;

        /**
         * sub 该JWT所面向的用户
         */
        @JSONField(name = "sub")
        private String sub;

        /**
         * email 用户的电子邮件地址
         */
        @JSONField(name = "email")
        private String email;

        /**
         * email_verified 用户的电子邮件地址是否已通过电子邮件验证
         */
        @JSONField(name = "email_verified")
        private Boolean emailVerified;

        /**
         * nbf 令牌的不早于时间
         */
        @JSONField(name = "nbf")
        private Long nbf;

        /**
         * name 用户的完整名称
         */
        @JSONField(name = "name")
        private String name;

        /**
         * picture 用户的个人资料图片的URL
         */
        @JSONField(name = "picture")
        private String picture;

        /**
         * given_name 用户的名字
         */
        @JSONField(name = "given_name")
        private String givenName;

        /**
         * locale 用户的语言环境
         */
        @JSONField(name = "locale")
        private String locale;

        /**
         * iat 令牌的签发时间
         */
        @JSONField(name = "iat")
        private Long iat;

        /**
         * exp 令牌的过期时间
         */
        @JSONField(name = "exp")
        private Long exp;

        /**
         * jti 令牌的唯一标识符
         */
        @JSONField(name = "jti")
        private String jti;
    }

    @SneakyThrows
    public static Result getResult(Param param, String clientId){
        // 获取谷歌凭证
        String idTokenString = param.getCredential();

        HttpTransport transport = new NetHttpTransport();
        JsonFactory jsonFactory = new GsonFactory();

        GoogleIdTokenVerifier verifier = new GoogleIdTokenVerifier.Builder(transport, jsonFactory)
                .setAudience(Collections.singletonList(clientId))
                .build();

        // 验证码谷歌凭证
        GoogleIdToken idToken = verifier.verify(idTokenString);
        if (idToken != null) {
            // 如果谷歌凭证有效，则获取谷歌凭证信息
            GoogleIdToken.Payload payload = idToken.getPayload();
            String sub = payload.getSubject();
            String email = payload.getEmail();
            boolean emailVerified = Boolean.valueOf(payload.getEmailVerified());
            String name = (String) payload.get("name");
            String pictureUrl = (String) payload.get("picture");
            String locale = (String) payload.get("locale");
            String familyName = (String) payload.get("family_name");
            String givenName = (String) payload.get("given_name");
            Result result = new Result();
            result.setIss(payload.getIssuer())
                    .setAzp(payload.getAuthorizedParty())
                    .setAud(payload.getAuthorizedParty())
                    .setSub(payload.getSubject())
                    .setEmail(payload.getEmail())
                    .setEmailVerified(Boolean.valueOf(payload.getEmailVerified()))
                    .setNbf(payload.getNotBeforeTimeSeconds())
                    .setName((String) payload.get("name"))
                    .setPicture((String) payload.get("picture"))
                    .setGivenName((String) payload.get("given_name"))
                    .setLocale((String) payload.get("locale"))
                    .setIat(payload.getIssuedAtTimeSeconds())
                    .setExp(payload.getExpirationTimeSeconds())
                    .setJti(payload.getJwtId());
            return result;
        }
        // 如果谷歌凭证无效，则抛出异常
        throw ThirdPartyGoogleException.GOOGLE_CREDENTIAL_INVALID;
    }


}
